Skip to content

fix(embed): join startup workers and preserve service failures - #28656

Merged
XuPeng-SH merged 3 commits into
matrixorigin:mainfrom
XuPeng-SH:fix/embed-startup-diagnostics
Sep 11, 2026
Merged

XuPeng-SH merged 3 commits into
matrixorigin:mainfrom
XuPeng-SH:fix/embed-startup-diagnostics

Conversation

@XuPeng-SH

@XuPeng-SH XuPeng-SH commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • BUG
  • Test and CI

Which issue(s) this PR fixes:

Related: #28419

What this PR does / why we need it:

Embedded cluster startup can launch CN workers concurrently, but the previous implementation stored heterogeneous startup errors in one atomic.Value. Different concrete error types can panic while being stored, and a synchronous LOG/TN failure could return while an already-launched CN worker was still starting. That lets rollback overlap startup and hides the original failure.

The startup path now owns one error slot per service, joins every launched CN worker before returning, keeps errors in service configuration order, preserves errors.Is/errors.As, and stops scheduling services after a synchronous infrastructure failure. The fix applies to initial and incremental startup. The regression tests use the existing startFn seam, so they do not start real services or add sleeps.

The error wrapper uses MatrixOne's typed internal error to satisfy the repository SCA contract. The concurrent-error oracle has been updated to assert the resulting diagnostic while retaining the cause and ordering checks.

Validation

  • Focused startup selection is non-empty and passes in normal mode.
  • TestDoStartLockedConcurrentErrors: -race -count=100, passed (1.192s).
  • TestDoStartLockedJoinsCNBeforeReturningInfrastructureFailure: -race -count=100, passed (1.194s).
  • Full pkg/embed normal: passed (49.268s).
  • Full pkg/embed race: passed (55.684s).
  • go vet ./pkg/embed/...: passed.
  • Incremental golangci-lint --new-from-rev origin/main ./pkg/embed/...: 0 issues.
  • git diff --check: passed.

The tests were run from the rebased candidate worktree at main ee0c2bf563bf27ff2c80891bb57a1de5886bf90b with a freshly built CPU CGo/native dependency set. The first vet attempt hit a full /tmp before analysis; it was rerun with disk-backed temporary storage and passed.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@matrix-meow matrix-meow added the size/M Denotes a PR that changes [100,499] lines label Sep 11, 2026
@XuPeng-SH
XuPeng-SH force-pushed the fix/embed-startup-diagnostics branch from 89cc564 to 490e0ff Compare September 11, 2026 03:05

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 12e7513 against main ee0c2bf. No concrete new blocker found; COMMENT only for this self-authored PR.

Each launched CN writes a distinct preallocated error slot. WaitGroup completion precedes reading those slots, returning to Start/StartNewCNService, and rollback. Thus heterogeneous error types no longer go through atomic.Value, all returned failures remain in the error tree in configuration order, and a synchronous infrastructure failure stops further scheduling without abandoning earlier CN workers. The result array is invocation-local, so incremental starts and subsequent attempts cannot inherit old errors. Normal startup retains CN concurrency with bounded O(service count) additional storage.

I traced the caller cleanup boundaries: initial startup rolls back only after the join; incremental startup retains its existing rollback/pending-cleanup ownership. The service object is transferred to the operator before its Start call, and failed Close retains ownership. The change does not introduce a new callback/cluster-lock dependency in the normal service startup path.

Important limits: join is not cancellation or a global startup deadline. Existing readiness waits have their own bounds, but service construction/Start and a deliberately blocking startFn are not universally bounded by this helper. CN-only startup already waited for all workers; the new wait after synchronous infrastructure failure intentionally trades early return for safe ownership. A worker panic is still a process panic, not a collected service error. These are not newly solved guarantees.

One non-blocking API clarification: errors.Is still finds the original cause, and errors.As finds distinct concrete cause types such as os.PathError as tested. However, because the attribution wrapper is itself a *moerr.Error and precedes the cause in errors.Join, errors.As into *moerr.Error selects the new internal-error wrapper before an underlying typed MO error. Do not describe this as preserving every errors.As selection/error code unchanged; I found no affected startup consumer requiring the old selection.

The deterministic tests cover heterogeneous causes, ordering/identity, an incremental success after failure, and joining an earlier CN before returning a later LOG failure while not starting TN. Existing rollback tests remain. Optional latch deadlines would make a scheduling regression fail faster than the package timeout; they are not evidence of a current false pass.

Evidence/limits: complete two-file diff, PR discussion/history, exact-head initial/incremental startup, operator ownership/readiness and cleanup paths inspected; head/base rechecked. Reported full-package/race repetitions/vet/lint are author evidence, not independent reruns. No new service startup, fault run or CI wait.

@XuPeng-SH
XuPeng-SH merged commit 4a7bfac into matrixorigin:main Sep 11, 2026
37 of 39 checks passed
VioletQwQ-0 pushed a commit to VioletQwQ-0/matrixone that referenced this pull request Sep 17, 2026
…xorigin#28656)

## What type of PR is this?

- [x] BUG
- [x] Test and CI

## Which issue(s) this PR fixes:

Related: matrixorigin#28419 

## What this PR does / why we need it:

Embedded cluster startup can launch CN workers concurrently, but the
previous implementation stored heterogeneous startup errors in one
`atomic.Value`. Different concrete error types can panic while being
stored, and a synchronous LOG/TN failure could return while an
already-launched CN worker was still starting. That lets rollback
overlap startup and hides the original failure.

The startup path now owns one error slot per service, joins every
launched CN worker before returning, keeps errors in service
configuration order, preserves `errors.Is`/`errors.As`, and stops
scheduling services after a synchronous infrastructure failure. The fix
applies to initial and incremental startup. The regression tests use the
existing `startFn` seam, so they do not start real services or add
sleeps.

The error wrapper uses MatrixOne's typed internal error to satisfy the
repository SCA contract. The concurrent-error oracle has been updated to
assert the resulting diagnostic while retaining the cause and ordering
checks.

## Validation

- Focused startup selection is non-empty and passes in normal mode.
- `TestDoStartLockedConcurrentErrors`: `-race -count=100`, passed
(1.192s).
- `TestDoStartLockedJoinsCNBeforeReturningInfrastructureFailure`: `-race
-count=100`, passed (1.194s).
- Full `pkg/embed` normal: passed (49.268s).
- Full `pkg/embed` race: passed (55.684s).
- `go vet ./pkg/embed/...`: passed.
- Incremental `golangci-lint --new-from-rev origin/main
./pkg/embed/...`: 0 issues.
- `git diff --check`: passed.

The tests were run from the rebased candidate worktree at main
`ee0c2bf563bf27ff2c80891bb57a1de5886bf90b` with a freshly built CPU
CGo/native dependency set. The first vet attempt hit a full `/tmp`
before analysis; it was rerun with disk-backed temporary storage and
passed.
VioletQwQ-0 pushed a commit to VioletQwQ-0/matrixone that referenced this pull request Sep 17, 2026
…xorigin#28656)

## What type of PR is this?

- [x] BUG
- [x] Test and CI

## Which issue(s) this PR fixes:

Related: matrixorigin#28419 

## What this PR does / why we need it:

Embedded cluster startup can launch CN workers concurrently, but the
previous implementation stored heterogeneous startup errors in one
`atomic.Value`. Different concrete error types can panic while being
stored, and a synchronous LOG/TN failure could return while an
already-launched CN worker was still starting. That lets rollback
overlap startup and hides the original failure.

The startup path now owns one error slot per service, joins every
launched CN worker before returning, keeps errors in service
configuration order, preserves `errors.Is`/`errors.As`, and stops
scheduling services after a synchronous infrastructure failure. The fix
applies to initial and incremental startup. The regression tests use the
existing `startFn` seam, so they do not start real services or add
sleeps.

The error wrapper uses MatrixOne's typed internal error to satisfy the
repository SCA contract. The concurrent-error oracle has been updated to
assert the resulting diagnostic while retaining the cause and ordering
checks.

## Validation

- Focused startup selection is non-empty and passes in normal mode.
- `TestDoStartLockedConcurrentErrors`: `-race -count=100`, passed
(1.192s).
- `TestDoStartLockedJoinsCNBeforeReturningInfrastructureFailure`: `-race
-count=100`, passed (1.194s).
- Full `pkg/embed` normal: passed (49.268s).
- Full `pkg/embed` race: passed (55.684s).
- `go vet ./pkg/embed/...`: passed.
- Incremental `golangci-lint --new-from-rev origin/main
./pkg/embed/...`: 0 issues.
- `git diff --check`: passed.

The tests were run from the rebased candidate worktree at main
`ee0c2bf563bf27ff2c80891bb57a1de5886bf90b` with a freshly built CPU
CGo/native dependency set. The first vet attempt hit a full `/tmp`
before analysis; it was rerun with disk-backed temporary storage and
passed.
VioletQwQ-0 pushed a commit to VioletQwQ-0/matrixone that referenced this pull request Sep 17, 2026
…xorigin#28656)

## What type of PR is this?

- [x] BUG
- [x] Test and CI

## Which issue(s) this PR fixes:

Related: matrixorigin#28419 

## What this PR does / why we need it:

Embedded cluster startup can launch CN workers concurrently, but the
previous implementation stored heterogeneous startup errors in one
`atomic.Value`. Different concrete error types can panic while being
stored, and a synchronous LOG/TN failure could return while an
already-launched CN worker was still starting. That lets rollback
overlap startup and hides the original failure.

The startup path now owns one error slot per service, joins every
launched CN worker before returning, keeps errors in service
configuration order, preserves `errors.Is`/`errors.As`, and stops
scheduling services after a synchronous infrastructure failure. The fix
applies to initial and incremental startup. The regression tests use the
existing `startFn` seam, so they do not start real services or add
sleeps.

The error wrapper uses MatrixOne's typed internal error to satisfy the
repository SCA contract. The concurrent-error oracle has been updated to
assert the resulting diagnostic while retaining the cause and ordering
checks.

## Validation

- Focused startup selection is non-empty and passes in normal mode.
- `TestDoStartLockedConcurrentErrors`: `-race -count=100`, passed
(1.192s).
- `TestDoStartLockedJoinsCNBeforeReturningInfrastructureFailure`: `-race
-count=100`, passed (1.194s).
- Full `pkg/embed` normal: passed (49.268s).
- Full `pkg/embed` race: passed (55.684s).
- `go vet ./pkg/embed/...`: passed.
- Incremental `golangci-lint --new-from-rev origin/main
./pkg/embed/...`: 0 issues.
- `git diff --check`: passed.

The tests were run from the rebased candidate worktree at main
`ee0c2bf563bf27ff2c80891bb57a1de5886bf90b` with a freshly built CPU
CGo/native dependency set. The first vet attempt hit a full `/tmp`
before analysis; it was rerun with disk-backed temporary storage and
passed.

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working kind/test-ci size/M Denotes a PR that changes [100,499] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants